#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#include "iot_gpio_ex.h"
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "iot_gpio.h"
#include "iot_errno.h"
#include "iot_pwm.h"
#include "iot_i2c.h"
#include "iot_adc.h"

#include "hi_time.h"
#include "hi_io.h"
#include "hi_errno.h"
#include "hi_adc.h"

#include "oled_ssd1306.h"
#include "iot_watchdog.h"
#include "pca9555.h"

// === OLED 配置 ===
#define OLED_I2C_IDX      0
#define OLED_SDA          IOT_IO_NAME_GPIO_13
#define OLED_SCL          IOT_IO_NAME_GPIO_14
#define OLED_SDA_FUNC     IOT_IO_FUNC_GPIO_13_I2C0_SDA
#define OLED_SCL_FUNC     IOT_IO_FUNC_GPIO_14_I2C0_SCL

// === IR 伪光效应器 ===
#define IR_GPIO           IOT_IO_NAME_GPIO_7
#define IR_ADC_CHANNEL    IOT_ADC_CHANNEL_3
#define IR_THRESHOLD      1000
#define IR_LIGHT_GPIO     IOT_IO_NAME_GPIO_10
#define IR_LIGHT_FUNC     IOT_IO_FUNC_GPIO_10_GPIO

// === 光效传感器 ===
#define LIGHT_ADC_CHANNEL IOT_ADC_CHANNEL_4
#define LIGHT_AO_PIN      IOT_IO_NAME_GPIO_9
#define LIGHT_DO_PIN      IOT_IO_NAME_GPIO_8
#define LIGHT_THRESHOLD   600

#define DWHITE_LED        (0x38 + 0x07)
#define LED_OFF           0x00

static uint32_t light_value = 0;

// === OLED ===
void OLED_Init() {
    IoSetFunc(OLED_SDA, OLED_SDA_FUNC);
    IoSetFunc(OLED_SCL, OLED_SCL_FUNC);
    IoTI2cInit(OLED_I2C_IDX, 400000);
    usleep(50000);
    OledInit();
    OledFillScreen(0x00);
}

// === IR 初始化 ===
void IR_Init() {
    IoSetFunc(IR_GPIO, IOT_IO_FUNC_GPIO_7_GPIO);
    IoTGpioInit(IR_GPIO);
    IoSetFunc(IR_LIGHT_GPIO, IR_LIGHT_FUNC);
    IoTGpioInit(IR_LIGHT_GPIO);
    IoTGpioSetDir(IR_LIGHT_GPIO, IOT_GPIO_DIR_OUT);
}

// === 读取IR ===
uint16_t IR_ReadValue() {
    unsigned short val = 0;
    AdcRead(IR_ADC_CHANNEL, &val, IOT_ADC_EQU_MODEL_8, IOT_ADC_CUR_BAIS_DEFAULT, 0xFF);
    return val;
}

// === 光效传感器 ===
void LightSensor_Init() {
    IoTGpioInit(LIGHT_AO_PIN);
    IoSetFunc(LIGHT_AO_PIN, IOT_IO_FUNC_GPIO_9_GPIO);
    IoTGpioSetDir(LIGHT_AO_PIN, IOT_GPIO_DIR_IN);
    IoTGpioInit(LIGHT_DO_PIN);
    IoSetFunc(LIGHT_DO_PIN, IOT_IO_FUNC_GPIO_8_GPIO);
    IoTGpioSetDir(LIGHT_DO_PIN, IOT_GPIO_DIR_IN);
}

void GetLightData() {
    unsigned short data = 0;
    IotGpioValue do_value;
    AdcRead(LIGHT_ADC_CHANNEL, &data, IOT_ADC_EQU_MODEL_4, IOT_ADC_CUR_BAIS_DEFAULT, 0xff);
    IoTGpioGetInputVal(LIGHT_DO_PIN, &do_value);
    light_value = data;
    printf("Light AO: %d, DO: %d\r\n", data, do_value);
}

void LightDetectionTask(void *arg) {
    LightSensor_Init();
    while (1) {
        GetLightData();
        osDelay(200);
    }
}

// === OLED 显示线程 ===
void OledDisplayTask(void *arg) {
    char line1[32];
    char line2[32];
    while (1) {
        uint16_t irVal = IR_ReadValue();

        // IR OLED
        snprintf(line1, sizeof(line1), "IR: %u", irVal);
        OledFillScreen(0x00);
        OledShowString(0, 0, line1, 1);

        // Light OLED
        char light_status[16] = "DARK";
        if (light_value < LIGHT_THRESHOLD) {
            strcpy(light_status, "BRIGHT");
            SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, LED_OFF);
        } else {
            SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, DWHITE_LED);
        }
        snprintf(line2, sizeof(line2), "Light:%d %s", 1000 - light_value, light_status);
        OledShowString(0, 2, line2, 1);

        // 输出光效格式
        if (irVal < IR_THRESHOLD) {
            IoTGpioSetOutputVal(IR_LIGHT_GPIO, IOT_GPIO_VALUE1);
        } else {
            IoTGpioSetOutputVal(IR_LIGHT_GPIO, IOT_GPIO_VALUE0);
        }

        osDelay(200);
    }
}

// === 应用入口 ===
void AppMain(void) {
    OLED_Init();
    IR_Init();
    PCA9555Init();
    SetPCA9555GpioValue(PCA9555_PART1_IODIR, PCA9555_OUTPUT);
    SetPCA9555GpioValue(PCA9555_PART1_OUTPUT, LED_OFF);

    osThreadAttr_t attr = {
        .name = "IR_OLED_Task",
        .stack_size = 2048,
        .priority = osPriorityNormal,
    };
    osThreadNew(OledDisplayTask, NULL, &attr);

    attr.name = "LightTask";
    osThreadNew(LightDetectionTask, NULL, &attr);
}

APP_FEATURE_INIT(AppMain);
